Syntax10.Scn.Fnt Syntax10b.Scn.Fnt Syntax10i.Scn.Fnt InfoElems Alloc Syntax10.Scn.Fnt StampElems Alloc 30 May 95 "Title": OpenElems "Author": Christoph Steindl (CS) "Abstract": OpenElems perform a generic open command on the selected item. Depending on the suffix of the entry different commands are called. The items are collected automatically from the current directory. "Keywords": Opening files "Version": 1.0 "From": 22.05.95 15:39:15 "Until": "Changes": no changes "Hints": You can insert new suffix mappings by calling OpenElems.Add suffix command, can also be used to override the default mapping, i.e. OpenElems.Add Text MyEdit.Open will cause *.Text files to be opened with MyEdit. TableElems Alloc Syntax10.Scn.Fnt /table Suffix Command Text Edit.Open Kep Kelper.Open Dlg Dialog.Open Hex Hex.Open Draw Draw.Open Film Kelper.Open Cod Edit.Open Tool System.Open Mod Edit.Open html HTMLEdit.Open MODULE OpenElems; (** CS Standard mapping of suffices to commands: IMPORT Viewers, Texts, TextFrames, Oberon, PopupElems, Directories, Display, In; OpenElem* = POINTER TO OpenElemDesc; OpenElemDesc* = RECORD (PopupElems.ElemDesc) END; AutoDirElem* = POINTER TO AutoDirElemDesc; AutoDirElemDesc* = RECORD (OpenElemDesc) END; Str64 = ARRAY 64 OF CHAR; Entry = POINTER TO EntryDesc; EntryDesc = RECORD suffix: ARRAY 10 OF CHAR; cmd: Str64; next: Entry END; w: Texts.Writer; map: Entry; cnt: INTEGER; PROCEDURE ReadName (t: Texts.Text; pos: LONGINT; VAR name: ARRAY OF CHAR); VAR r: Texts.Reader; ch: CHAR; i: INTEGER; BEGIN Texts.OpenReader(r, t, pos); Texts.Read(r, ch); i := 0; IF ch = '"' THEN Texts.Read(r, ch); WHILE ~r.eot & (ch # '"') DO name[i] := ch; INC(i); Texts.Read(r, ch) END ELSE WHILE ~r.eot & (ch > " ") DO name[i] := ch; INC(i); Texts.Read(r, ch) END END; name[i] := 0X END ReadName; PROCEDURE GetSuffix(VAR str, suffix: ARRAY OF CHAR); VAR i, j: INTEGER; BEGIN i := 0; WHILE str[i] # 0X DO INC(i) END; WHILE (i >= 0) & (str[i] # ".") DO DEC(i) END; INC(i); j := 0; WHILE str[i] # 0X DO suffix[j] := str[i]; INC(i); INC(j) END; suffix[j] := 0X END GetSuffix; PROCEDURE Lookup(VAR suffix, cmd: ARRAY OF CHAR); VAR e: Entry; BEGIN e := map; WHILE (e # NIL) & (e.suffix # suffix) DO e := e.next END; IF e # NIL THEN COPY(e.cmd, cmd); ELSE COPY("Edit.Open", cmd) END Lookup; PROCEDURE Exec (e: OpenElem; f: Display.Frame; pos: LONGINT); VAR m: TextFrames.UpdateMsg; res: INTEGER; name: ARRAY 256 OF CHAR; suffix: ARRAY 10 OF CHAR; par: Oberon.ParList; cmd: ARRAY 64 OF CHAR; BEGIN ReadName(e.menu, pos, name); GetSuffix(name, suffix); Lookup(suffix, cmd); NEW(par); par.frame := f; par.text := e.menu; par.pos := pos; Oberon.Call(cmd, par, FALSE, res); IF res = 0 THEN m.id := TextFrames.replace; m.text := Texts.ElemBase(e); m.beg := Texts.ElemPos(e); m.end := m.beg + 1; Viewers.Broadcast(m) ELSE Texts.WriteString(w, " -- failed"); Texts.WriteLn(w); Texts.Append(Oberon.Log, w.buf) END Exec; PROCEDURE Handle* (e: Texts.Elem; VAR m: Texts.ElemMsg); VAR e1: OpenElem; BEGIN WITH e: OpenElem DO WITH m: Texts.CopyMsg DO IF m.e = NIL THEN NEW (e1); m.e := e1 END; PopupElems.Handle(e, m) | m: Texts.IdentifyMsg DO m.mod := "OpenElems"; m.proc := "Alloc" | m: PopupElems.ExecMsg DO Exec(e, m.frame, m.pos) ELSE PopupElems.Handle(e, m) END END Handle; PROCEDURE Alloc*; VAR e: OpenElem; BEGIN NEW(e); e.handle := Handle; Texts.new := e END Alloc; PROCEDURE Insert*; VAR e: OpenElem; insert: TextFrames.InsertElemMsg; s: Texts.Scanner; BEGIN NEW(e); e.handle := Handle; e.small := TRUE; Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(s); IF ~(s.class IN {Texts.Name, Texts.String}) THEN s.s := "OpenElem" END; COPY(s.s, e.name); e.menu := TextFrames.Text(""); PopupElems.MeasureMenu(e); insert.e := e; Viewers.Broadcast(insert) END Insert; PROCEDURE AddEntry (suffix, cmd: Str64); VAR e: Entry; BEGIN NEW(e); COPY(suffix, e.suffix); COPY(cmd, e.cmd); IF (e.suffix # "") & (e.cmd # "") THEN e.next := map; map := e END AddEntry; PROCEDURE Add*; (* suffix command *) VAR suffix, cmd: Str64; BEGIN In.Open; In.Name(suffix); In.Name(cmd); AddEntry(suffix, cmd) END Add; PROCEDURE ListProc (VAR name: ARRAY OF CHAR; time, date, length: LONGINT; isDir: BOOLEAN; VAR continue: BOOLEAN); BEGIN Texts.WriteString (w, name); Texts.WriteLn (w); INC(cnt) END ListProc; PROCEDURE CollectFiles (e: OpenElem); VAR volName: ARRAY 32 OF CHAR; vRefNum: INTEGER; dirID: LONGINT; BEGIN e.menu := TextFrames.Text(""); Directories.GetCurDir (volName, vRefNum, dirID); cnt := 0; Directories.EnumerateFiles (vRefNum, dirID, e.name, ListProc); IF cnt = 1 THEN Texts.WriteLn(w) END; (* prohibit AutoDirElems that do not pop up because they only contain one item *) IF w.buf.len = 0 THEN Texts.WriteString (w, "no files found"); Texts.WriteLn (w); Texts.WriteLn (w) END; Texts.Append(e.menu, w.buf); PopupElems.MeasureMenu(e) END CollectFiles; PROCEDURE HandleAutoDir* (e: Texts.Elem; VAR m: Texts.ElemMsg); VAR e1: AutoDirElem; BEGIN WITH e: AutoDirElem DO WITH m: Texts.CopyMsg DO IF m.e = NIL THEN NEW (e1); m.e := e1 END; Handle(e, m) | m: Texts.IdentifyMsg DO m.mod := "OpenElems"; m.proc := "AllocAutoDir" | m: TextFrames.TrackMsg DO IF 1 IN m.keys THEN CollectFiles (e); Handle (e, m) END ELSE Handle(e, m) END END HandleAutoDir; PROCEDURE AllocAutoDir*; VAR e: AutoDirElem; BEGIN NEW(e); e.handle := HandleAutoDir; Texts.new := e END AllocAutoDir; PROCEDURE InsertAutoDir*; VAR e: AutoDirElem; insert: TextFrames.InsertElemMsg; BEGIN NEW(e); e.handle := HandleAutoDir; e.small := TRUE; e.name := "*"; e.menu := TextFrames.Text(""); PopupElems.MeasureMenu(e); insert.e := e; Viewers.Broadcast(insert) END InsertAutoDir; BEGIN Texts.OpenWriter(w); AddEntry("Text", "Edit.Open"); AddEntry("Kep", "Kepler.Open"); AddEntry("Dlg", "Dialog.Open"); AddEntry("Hex", "Hex.Open"); AddEntry("Draw", "Draw.Open"); AddEntry("Film", "Kepler.Open"); AddEntry("Cod", "Edit.Open"); AddEntry("Tool", "System.Open"); AddEntry("Mod", "Edit.Open"); AddEntry("html", "HTMLEdit.Open") END OpenElems.Insert OpenElems.InsertAutoDir